import { Request, Response } from 'express';
import { AuthRequest } from '@/types';
import dictService from '@/services/system/dict.service';
import ApiResponse from '@/utils/api/api-response.util';
import { getLogger } from '@/utils/logger';
import { Log, BusinessType } from '@/decorators/Log';
import { RepeatSubmit } from '@/decorators/repeatSubmit.decorator';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("dict-controller");
const logger = getLogger("dict-controller", {
	console: false,
});

class DictController {
  /**
   * 根据字典类型查询字典数据信息
   * @param req 请求对象
   * @param res 响应对象
   */
  async type(req: Request, res: Response) {
    try {
      const dictType = req.params.dictType;
      
      // 请求日志
      consoleLogger.info("请求字典类型数据", {
        params: req.params,
        operator: req.user?.userName || 'unknown',
      });
      
      // 根据字典类型查询字典数据
      const data = await dictService.selectDictDataByType(dictType);
      
      // 结果日志
      logger.info("获取字典类型数据成功", {
        response: {
          dictType,
          dataCount: data?.length || 0,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, data);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`查询字典类型数据失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '查询字典类型数据失败', 500);
      }
    }
  }
  
  /**
   * 获取字典类型列表
   * @param req 请求对象
   * @param res 响应对象
   */
  async listType(req: AuthRequest, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取字典类型列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const result = await dictService.selectDictTypeList(req.query);
      
      // 结果日志
      logger.info("获取字典类型列表成功", {
        response: {
          total: result.total,
          count: result.rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithTable(res, result.rows, result.total);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取字典类型列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '获取字典类型列表失败', 500);
      }
    }
  }
  
  /**
   * 获取字典数据列表
   * @param req 请求对象
   * @param res 响应对象
   */
  async listData(req: AuthRequest, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取字典数据列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const result = await dictService.selectDictDataList(req.query);
      
      // 结果日志
      logger.info("获取字典数据列表成功", {
        response: {
          total: result.total,
          count: result.rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithTable(res, result.rows, result.total);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取字典数据列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '获取字典数据列表失败', 500);
      }
    }
  }
  
  /**
   * 获取字典类型详细信息
   * @param req 请求对象
   * @param res 响应对象
   */
  async getType(req: AuthRequest, res: Response) {
    try {
      const dictId = parseInt(req.params.dictId);
      
      // 请求日志
      consoleLogger.info("获取字典类型详情请求", {
        params: req.params,
        dictId,
        operator: req.user?.userName || 'unknown',
      });
      
      const dictType = await dictService.selectDictTypeById(dictId);
      
      if (!dictType) {
        consoleLogger.warn('获取字典类型详情 - 字典类型不存在', { dictId });
        ApiResponse.error(res, '字典类型不存在', 500);
        return;
      }
      
      // 结果日志
      logger.info("获取字典类型详情成功", {
        response: {
          dictId,
          dictType,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, dictType);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取字典类型详细信息失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '获取字典类型详细信息失败', 500);
      }
    }
  }
  
  /**
   * 获取字典数据详细信息
   * @param req 请求对象
   * @param res 响应对象
   */
  async getData(req: AuthRequest, res: Response) {
    try {
      const dictCode = parseInt(req.params.dictCode);
      
      // 请求日志
      consoleLogger.info("获取字典数据详情请求", {
        params: req.params,
        dictCode,
        operator: req.user?.userName || 'unknown',
      });
      
      const dictData = await dictService.selectDictDataById(dictCode);
      
      if (!dictData) {
        consoleLogger.warn('获取字典数据详情 - 字典数据不存在', { dictCode });
        ApiResponse.error(res, '字典数据不存在', 500);
        return;
      }
      
      // 结果日志
      logger.info("获取字典数据详情成功", {
        response: {
          dictCode,
          dictData,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, dictData);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取字典数据详细信息失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '获取字典数据详细信息失败', 500);
      }
    }
  }

  /**
   * 新增字典类型
   * @param req 请求对象
   * @param res 响应对象
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '字典类型', businessType: BusinessType.INSERT })
  async addType(req: AuthRequest, res: Response) {
    try {
      const dictType = req.body;
      
      // 请求日志
      consoleLogger.info("新增字典类型请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      dictType.createBy = req.user?.userName || 'admin';
      
      const result = await dictService.insertDictType(dictType);
      
      // 结果日志
      logger.info("新增字典类型成功", {
        response: {
          dictType: dictType.dictType,
          result,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '新增成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`新增字典类型失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '新增字典类型失败', 500);
      }
    }
  }

  /**
   * 修改字典类型
   * @param req 请求对象
   * @param res 响应对象
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '字典类型', businessType: BusinessType.UPDATE })
  async updateType(req: AuthRequest, res: Response) {
    try {
      const dictType = req.body;
      
      // 请求日志
      consoleLogger.info("修改字典类型请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      dictType.updateBy = req.user?.userName || 'admin';
      
      const result = await dictService.updateDictType(dictType);
      
      // 结果日志
      logger.info("修改字典类型成功", {
        response: {
          dictId: dictType.dictId,
          dictType: dictType.dictType,
          result,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '修改成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`修改字典类型失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '修改字典类型失败', 500);
      }
    }
  }

  /**
   * 删除字典类型（支持批量删除，逗号分隔多个ID）
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '字典类型', businessType: BusinessType.DELETE })
  async removeType(req: AuthRequest, res: Response) {
    try {
      const dictIds = req.params.dictId.split(',').map((id: string) => parseInt(id));
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("删除字典类型请求", {
        params: req.params,
        dictIds,
        operator,
      });
      
      const result = await dictService.deleteDictTypeByIds(dictIds);
      
      // 结果日志
      logger.info("删除字典类型成功", {
        response: {
          dictIds,
          result,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '删除成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`删除字典类型失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '删除字典类型失败', 500);
      }
    }
  }

  /**
   * 新增字典数据
   * @param req 请求对象
   * @param res 响应对象
   */
  @RepeatSubmit()
  @Log({ title: '字典数据', businessType: BusinessType.INSERT })
  async addData(req: AuthRequest, res: Response) {
    try {
      const dictData = req.body;
      
      // 请求日志
      consoleLogger.info("新增字典数据请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      dictData.createBy = req.user?.userName || 'admin';
      
      const result = await dictService.insertDictData(dictData);
      
      // 结果日志
      logger.info("新增字典数据成功", {
        response: {
          dictData: dictData.dictValue,
          result,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '新增成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`新增字典数据失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '新增字典数据失败', 500);
      }
    }
  }

  /**
   * 修改字典数据
   * @param req 请求对象
   * @param res 响应对象
   */
  @RepeatSubmit()
  @Log({ title: '字典数据', businessType: BusinessType.UPDATE })
  async updateData(req: AuthRequest, res: Response) {
    try {
      const dictData = req.body;
      
      // 请求日志
      consoleLogger.info("修改字典数据请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      dictData.updateBy = req.user?.userName || 'admin';
      
      const result = await dictService.updateDictData(dictData);
      
      // 结果日志
      logger.info("修改字典数据成功", {
        response: {
          dictCode: dictData.dictCode,
          dictValue: dictData.dictValue,
          result,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '修改成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`修改字典数据失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '修改字典数据失败', 500);
      }
    }
  }

  /**
   * 删除字典数据（支持批量删除，逗号分隔多个ID）
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '字典数据', businessType: BusinessType.DELETE })
  async removeData(req: AuthRequest, res: Response) {
    try {
      const dictCodes = req.params.dictCode.split(',').map((id: string) => parseInt(id));
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("删除字典数据请求", {
        params: req.params,
        dictCodes,
        operator,
      });
      
      const result = await dictService.deleteDictDataByIds(dictCodes);
      
      // 结果日志
      logger.info("删除字典数据成功", {
        response: {
          dictCodes,
          result,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '删除成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`删除字典数据失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '删除字典数据失败', 500);
      }
    }
  }

  /**
   * 获取字典类型下拉选择框
   * @param req 请求对象
   * @param res 响应对象
   */
  async optionselect(req: AuthRequest, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取字典类型下拉选择框请求", {
        operator: req.user?.userName || 'unknown',
      });
      
      const options = await dictService.selectDictTypeOptions();
      
      // 结果日志
      logger.info("获取字典类型下拉选择框成功", {
        response: {
          optionsCount: options?.length || 0,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, options);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取字典类型下拉选项失败: ${error instanceof Error ? error.message : String(error)}`, {
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '获取字典类型下拉选项失败', 500);
      }
    }
  }

  /**
   * 导出字典数据为 Excel
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '字典数据', businessType: BusinessType.EXPORT })
  async exportData(req: AuthRequest, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("导出字典数据请求", {
        body: req.body,
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const params = Object.keys(req.body || {}).length > 0 ? req.body : req.query;
      const buffer = await dictService.exportDictDataToExcel(params);
      
      // 结果日志
      logger.info("导出字典数据成功", {
        response: {
          params,
          bufferSize: buffer?.length || 0,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.setHeader('Content-Disposition', 'attachment; filename="dict-data.xlsx"');
      res.end(buffer);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`导出字典数据失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '导出字典数据失败', 500);
      }
    }
  }

  /**
   * 刷新字典缓存
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '字典类型', businessType: BusinessType.CLEAN })
  async refreshCache(req: AuthRequest, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("刷新字典缓存请求", {
        operator: req.user?.userName || 'unknown',
      });
      
      await dictService.refreshCache();
      
      // 结果日志
      logger.info("刷新字典缓存成功", {
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '字典缓存刷新成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`刷新字典缓存失败: ${error instanceof Error ? error.message : String(error)}`, {
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '刷新字典缓存失败', 500);
      }
    }
  }

  /**
   * 导出字典类型为 Excel
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '字典类型', businessType: BusinessType.EXPORT })
  async exportType(req: AuthRequest, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("导出字典类型请求", {
        body: req.body,
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const params = Object.keys(req.body || {}).length > 0 ? req.body : req.query;
      const buffer = await dictService.exportDictTypeToExcel(params);
      
      // 结果日志
      logger.info("导出字典类型成功", {
        response: {
          params,
          bufferSize: buffer?.length || 0,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.setHeader('Content-Disposition', 'attachment; filename="dict-type.xlsx"');
      res.end(buffer);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`导出字典类型失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '导出字典类型失败', 500);
      }
    }
  }
}

export default new DictController(); 